package com.srolorz.fmtp.thread.pool.executor.properties;

import com.srolorz.fmtp.thread.pool.executor.ApplicationContext;
import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotationMetadata;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * @author eleven
 */
public class BeanPropertiesBindRegistrar implements ImportBeanDefinitionRegistrar, EnvironmentAware {
    private static final Logger LOGGER = LoggerFactory.getLogger(BeanPropertiesBindRegistrar.class);
    private Environment env;
    private Binder binder;

    @Override
    public void setEnvironment(Environment environment){
        LOGGER.info("set environment and bind");
        this.env = environment;
        this.binder = Binder.get(this.env);
    }

    @Override
    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) {
        LOGGER.info("init bind properties...");
        List<Map> bindList = this.binder.bind("fmtp.thread.pool", Bindable.listOf(Map.class)).get();
        List<ThreadPoolProperties> list = new ArrayList<>();
        bindList.stream().forEach(bvalue -> {
            Map<String, Object> valueMap = new HashMap<>();
            Iterator iterator = bvalue.entrySet().iterator();
            while (iterator.hasNext()){
                Map.Entry entry = (Map.Entry) iterator.next();
                valueMap.put(entry.getKey().toString(), entry.getValue());
            }
            ThreadPoolProperties threadPoolProperties = new ThreadPoolProperties();
            try {
                BeanUtils.populate(threadPoolProperties, valueMap);
                list.add(threadPoolProperties);
            } catch (Exception e) {
                LOGGER.error("error: bind thread pool properties failed!",e);
            }
        });
        ApplicationContext.build().add("threadPoolProperties", list);
    }
}
